package com.dog.modules.iot.mqtt.produce;

import com.alibaba.fastjson2.JSON;
import com.dog.framework.mqtt.component.MqttGateway;
import com.dog.framework.mqtt.config.MqttClientProperties;
import com.dog.framework.mqtt.config.MqttProducerProperties;
import com.dog.modules.iot.mqtt.codec.SecretKey;
import com.dog.modules.iot.dto.system.MqttConnectClientDTO;
import com.dog.modules.iot.mqtt.produce.bound.OutboundCommand;
import com.dog.modules.iot.mqtt.codec.SecretService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;
import java.util.Map;

/**
 * mqtt下发指令到设备的服务基类
 */
@Slf4j
@Service
public class RobotsMqttProducer {
    public static final String URL_MQTT_ALL_CLIENTS = "/api/v4/clients/";

    @Value(value = "${spring.mqtt.client.http-url}")
    private String httpUrl;

    public static final String STR_COLON = ":";
    public static final String AUTH_PREFIX_BASIC = "Basic ";
    public static final String AUTH_HEADER = "Authorization";

    private static final String STR_PARAM_SPLIT = "?_=";

    @Resource
    MqttClientProperties mqttClientProperties;
    @Resource
    MqttProducerProperties mqttProducerProperties;
    @Resource
    private MqttGateway mqttGateway;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private SecretService secretService;

    /**
     * 发送消息同时进行加密
     *
     * @param deviceCode
     * @param command
     */
    public void sendMqttMessageWithSecret(String deviceCode, OutboundCommand command) {
        SecretKey key = secretService.getSecretKey(deviceCode);
        if (key == null) {
            log.error("设备: " + deviceCode + "密钥不存在!");
        }
//            if (encode) {
        byte[] secret = key.getSecretKey().getBytes();
        byte[] iv = key.getIv().getBytes();
        command.encodeData(secret, iv);
//            }
        log.info("mqtt send cmd[{}] to device[{}] with data[{}] ", command.getHeader().getCmd(), deviceCode, command);
        mqttGateway.sendToMqtt(mqttProducerProperties.getTopicPrefix() + deviceCode, command.toString(), 2);
    }

    public void sendMqttDroppedMessage(String deviceCode, String payload) {
        log.info("mqtt resend dropped msg[{}] to device[{}] ", payload, deviceCode);
        mqttGateway.sendToMqtt(mqttProducerProperties.getTopicPrefix() + deviceCode, payload, 2);
    }

    /**
     * 获取连接到mqtt服务上的所有clients
     *
     * @return 连接客户端列表
     */
    public List<MqttConnectClientDTO> getAllClients() {
        String encodeStr = mqttClientProperties.getUsername() + STR_COLON + mqttClientProperties.getPassword();
        String authHeader = AUTH_PREFIX_BASIC + Base64.getEncoder().encodeToString(encodeStr.getBytes(StandardCharsets.UTF_8));
        HttpHeaders httpHeaders = new HttpHeaders() {{
            set(AUTH_HEADER, authHeader);
        }};
        String nodeUrl = httpUrl + URL_MQTT_ALL_CLIENTS;
        ResponseEntity<Map> result = restTemplate
                .exchange(nodeUrl + STR_PARAM_SPLIT + System.currentTimeMillis(), HttpMethod.GET, new HttpEntity<String>(httpHeaders), Map.class);
        if (result.getBody() != null) {
            List<MqttConnectClientDTO> data = JSON.parseArray(JSON.toJSONString(result.getBody().get("data")), MqttConnectClientDTO.class);
            return data;
        }
        return null;
    }

    public List<MqttConnectClientDTO> getClientsById(String clientId) {
        String encodeStr = mqttClientProperties.getUsername() + STR_COLON + mqttClientProperties.getPassword();
        String authHeader = AUTH_PREFIX_BASIC + Base64.getEncoder().encodeToString(encodeStr.getBytes(StandardCharsets.UTF_8));
        HttpHeaders httpHeaders = new HttpHeaders() {{
            set(AUTH_HEADER, authHeader);
        }};
        String nodeUrl = httpUrl + URL_MQTT_ALL_CLIENTS + clientId;
        ResponseEntity<Map> result = restTemplate
                .exchange(nodeUrl + STR_PARAM_SPLIT + System.currentTimeMillis(), HttpMethod.GET, new HttpEntity<String>(httpHeaders), Map.class);
        if (result.getBody() != null) {
            List<MqttConnectClientDTO> data = JSON.parseArray(JSON.toJSONString(result.getBody().get("data")), MqttConnectClientDTO.class);
            return data;
        }
        return null;
    }


}
